
package com.jbpm.interceptor;

import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;

import com.emms.common.constant.CommonConstant;
import com.emms.common.util.BaseUtil;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;


/**
 * 功能说明：登录拦截器
 * @作者：罗明俊
 * @创建日期： 2012-08-20
 */
public class LoginInterceptor extends AbstractInterceptor {
	/**
	 * 
	 */
	private static final long serialVersionUID = -2884243662434423013L;
	
	//登录用户名字段
	private String loginUserName = "username";

	public String getLoginUserName() {
		return loginUserName;
	}

	public void setLoginUserName(String loginUserName) {
		this.loginUserName = loginUserName;
	}



	//判断是否重复登录
	@SuppressWarnings("unchecked")
	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
		
		//request
		HttpServletRequest request=ServletActionContext.getRequest();
		//当前session
		HttpSession session =request.getSession();
		//从服务器容器中获取
		ServletContext sc = ServletActionContext.getServletContext();
		//当前请求路径
		String path=request.getServletPath();
//		if(session!=null){
//			System.out.println(session.getId());
//		}
		//当前是否登录
	    SysUserLoginBean userlogin=(SysUserLoginBean) session.getAttribute(CommonConstant.SESSION_USER);
		if(BaseUtil.isEmpty(userlogin) && path.indexOf(CommonConstant.LOGINPATH)<0){
			//获取方法
			String methodName = invocation.getProxy().getMethod();
			Method method = invocation.getAction().getClass().getMethod(methodName);			
			if(method.isAnnotationPresent(NoInterceptor.class)){
				//NoInterceptor noInterceptor = method.getAnnotation(NoInterceptor.class);
            	//无需拦截
            	return invocation.invoke();
			}else{
				String reLoginMessage = "<script type='text/javascript'>" + "alert('未登录或超时,请重新登录后再访问!');"
						+ "window.top.location.href='" + sc.getContextPath() + "/page/tracelogin.jsp';" + "</script>";
				ServletActionContext.getResponse().setHeader("content-type", "text/html; charset=utf-8");
				//强制输出
				PrintWriter out = ServletActionContext.getResponse().getWriter();
				// 页面上显示
				out.println(reLoginMessage);
				out.flush();
				out.close();
				return null;
				
			}
		}
		
		//在线用户列表
		Map<String, SysUserLoginBean> onlineUsersMap =(Map<String, SysUserLoginBean>) sc.getAttribute(CommonConstant.SERVLETCONTEXT_ONLINE_USER);
		// 如果取得用户列表为空
		if (BaseUtil.isEmpty(onlineUsersMap)) {
			//移除当前session用户信息
			//session.removeAttribute(CommonConstant.SESSION_USER);
			return invocation.invoke();
		}
		
		//在线用户session列表
		Map<String, SysUserLoginBean> onlineUserSessionMap = (Map<String, SysUserLoginBean>)sc.getAttribute(CommonConstant.SERVLETCONTEXT_SESSIONMAP);
		//是否被强制退出
		if(!BaseUtil.isEmpty(onlineUserSessionMap)){
			    //当前sessionId获取对象
				SysUserLoginBean userloginOld=onlineUserSessionMap.get(session.getId());
				if(!BaseUtil.isEmpty(userloginOld)){
					if(!userloginOld.getStatuts()){//不正常---被强制退出
						//移除当前session用户信息
						session.removeAttribute(CommonConstant.SESSION_USER);
						//从在线map中把他移除
						onlineUserSessionMap.remove(session.getId());
						//--在线用户id是否与此相同
						SysUserLoginBean onLineUser =onlineUsersMap.get(userloginOld.getUserName());
						if (!BaseUtil.isEmpty(onLineUser)) {
							if(onLineUser.getSessionId().equals(session.getId())){
								//若相同则一起移除
								onlineUsersMap.remove(userloginOld.getUserName());
							}
						}
						//更新容器
						sc.setAttribute(CommonConstant.SERVLETCONTEXT_ONLINE_USER, onlineUsersMap);
						sc.setAttribute(CommonConstant.SERVLETCONTEXT_SESSIONMAP, onlineUserSessionMap);
						
						String reLoginMessage = "<script type='text/javascript'>" + "alert('对不起该账号已经在其他地方登录!您被强制退出!');"
								+ "window.top.location.href='" + sc.getContextPath() + "/page/tracelogin.jsp';" + "</script>";
						ServletActionContext.getResponse().setHeader("content-type", "text/html; charset=utf-8");
						//强制输出
						PrintWriter out = ServletActionContext.getResponse().getWriter();
						// 页面上显示
						out.println(reLoginMessage);
						out.flush();
						out.close();
						return null;
					}else if(userloginOld.getStatuts()){//帐号正常
						//是否登录--若是则直接跳到主页
						if(path.indexOf(CommonConstant.LOGINPATH)>=0){
							String reLoginMessage = "<script type='text/javascript'>" + "alert('您已经登录过,将为你转入到主页!');"
									+ "window.top.location.href='" + sc.getContextPath() + "/page/main.jsp';" + "</script>";
							ServletActionContext.getResponse().setHeader("content-type", "text/html; charset=utf-8");
							//强制输出
							PrintWriter out = ServletActionContext.getResponse().getWriter();
							// 页面上显示
							out.println(reLoginMessage);
							out.flush();
							out.close();
							return null;
						}else{
							return invocation.invoke();
						}
					}
				
			}else{
				//其他地方或者浏览器登录情况--进行登录
				if(path.indexOf(CommonConstant.LOGINPATH)>=0){
					//获取登录用户名--
					String userName = invocation.getStack().findString(loginUserName);
					//是否存在在线用户列表中
					SysUserLoginBean onLineUserOld =onlineUsersMap.get(userName);
					if (!BaseUtil.isEmpty(onLineUserOld)) {//-------------已经登录过
						//说明存在
						//重新更新状态
						onLineUserOld.setStatuts(false);//强制退出
						if(onlineUserSessionMap.containsKey(onLineUserOld.getSessionId())){
							//判断是否存在以前的列表中
							onlineUserSessionMap.remove(onLineUserOld.getSessionId());
							onlineUserSessionMap.put(onLineUserOld.getSessionId(), onLineUserOld);
						}else{
							onlineUserSessionMap.put(onLineUserOld.getSessionId(), onLineUserOld);
						}
						//进行把之前的移除掉--让后登录着进入系统
						onlineUsersMap.remove(userName);
						//是否已经登录过
						invocation.getStack().setValue("isLogin",true);
						//更新容器
						sc.setAttribute(CommonConstant.SERVLETCONTEXT_ONLINE_USER, onlineUsersMap);
						sc.setAttribute(CommonConstant.SERVLETCONTEXT_SESSIONMAP, onlineUserSessionMap);
						return invocation.invoke();
					}else{//没登录可以继续登录
						return invocation.invoke();
					}
				}else{
					return invocation.invoke();
				}
			}
		}else{
			//移除当前session用户信息
			session.removeAttribute(CommonConstant.SESSION_USER);
			return invocation.invoke();
		}
		return invocation.invoke();
		
	}
	
	/**
	 * 判断是否需要拦截
	 * 由于。。之前开放人员配置访问方法问题导致
	 * <param name="excludeMethods">initProjectsByUsername,initOrgsByProjectid,valUser,userLogin,exitLogin</param>
	 * 不能生效，所以暂时采用以下方式处理
	 * @param path
	 * @return
	 */
	/*private boolean noInvoke(String path){
		if(BaseUtil.isEmpty(path))return true;
		//进行判断是否登录处理
		if (path.indexOf("/authorization!initProjectsByUsername")>=0) {
			return true;
		} else if (path.indexOf("/authorization!initOrgsByProjectid")>=0) {
			return true;
		} else if (path.indexOf("/authorization!valUser")>=0) {
			return true;
		}
		else if (path.indexOf("/authorization!userLogin")>=0) {
			return true;
		}else if (path.indexOf("/authorization!exitLogin")>=0) {
			return true;
		}else if(path.indexOf("printPage")>=0){
			return true;
		}
		else{
			//必须登录
			return false;
		}
	}*/
}
